package frame

import (
	"embed"
	"gitee.com/git_public/vfaith/builtin/bean"
	"gitee.com/git_public/vfaith/fount/handle"
	"gitee.com/git_public/vfaith/fount/middleware"
	"gitee.com/git_public/vfaith/sugar"
	"gitee.com/git_public/vfaith/sugar/regexpv"
	"go/ast"
	"go/parser"
	"go/token"
	"log"
	"net/http"
	"os"
	"reflect"
	"runtime"
	"strings"
)

type IxBaseAction interface {
	ActionInitialize()
}

//region 匹配路由进行HttpHandle注册

func RouterRegister[T IxBaseAction](structTyp T, fs *embed.FS) {
	typ := reflect.TypeOf(structTyp)
	v := reflect.ValueOf(structTyp)

	method, _ := typ.MethodByName("ActionInitialize")
	if !method.Func.IsValid() {
		log.Print("方法名ActionInitialize不存在，无法获取当前文件路径")
		return
	}
	filePath, _ := runtime.FuncForPC(method.Func.Pointer()).FileLine(0)

	//跳过代码自动生成的HTTP注册
	if strings.Index(filePath, "generate") > 0 {
		return
	}

	// 遍历查找当前Action匹配的Router
	var router bean.IxBaseRouter
	fb.routerMap.RangeStoreMap(func(name string, r bean.IxBaseRouter) {
		if strings.Index(filePath, r.AppPath()) >= 0 {
			if router != nil {
				log.Fatalf("出现重复的匹配！")
			}
			router = r
		}
	})
	if router == nil {
		log.Fatalf("%s没有匹配的Router！", typ.Elem().Name())
		//log.Printf("%s没有匹配的Router，使用默认HttpHandle！", typ.Elem().Name())
		//HttpRegister(filePath, v, fs)
		//return
	}

	// 读取文件内容
	src, err := os.ReadFile(filePath)
	if err != nil {
		//编译包必须使用内嵌文件读取，正常编译不会包含源码文件
		codePath := "expose" + strings.Split(filePath, "expose")[1]
		src, err = fs.ReadFile(codePath)
		if err != nil {
			log.Fatalf("Failed to read file: %v", err)
		}
	}

	// 创建一个文件集
	fSet := token.NewFileSet()
	file1, err2 := parser.ParseFile(fSet, filePath, src, parser.ParseComments)
	if err2 != nil {
		log.Fatalf("Failed to read file: %v", err2)
	}

	var prefix string
	var module string
	//遍历循环所有声明，包含【import、init、struct[GenDecl]、func[FuncDecl]】
	for _, decl := range file1.Decls {
		//判断GenDecl声明，针对结构体Action设定路径 ActionMapping("")
		if genDecl, ok := decl.(*ast.GenDecl); ok && genDecl.Tok == token.TYPE {
			if genDecl.Doc != nil {
				for _, comment := range genDecl.Doc.List {
					//log.Printf("Found comment: %s\n", comment.Text)
					actionMapping := regexpv.ActionMappingRegExp(comment.Text)
					if len(actionMapping) > 0 {
						prefix = actionMapping[0][1]
						log.Printf("ActionMapping: %s\n", actionMapping[0][1])
					}

					actionModule := regexpv.ActionModuleRegExp(comment.Text)
					if len(actionModule) > 0 {
						module = actionModule[0][1]
						log.Printf("ActionModule: %s\n", module)
					}
				}
			}
		}

		//判断FuncDecl声明，对相关action方法进行注册
		if funcDecl, okFunc := decl.(*ast.FuncDecl); okFunc && funcDecl.Doc != nil {
			for _, comment := range funcDecl.Doc.List {
				//log.Printf("Found comment: %s\n", comment.Text)
				cText := comment.Text

				//根据swagger方式进行路由注册
				matches1 := regexpv.SwaggerRouterRegExp(cText)
				if len(matches1) > 0 {
					routerFuncRegister(router, v, funcDecl, prefix, matches1[0][1])
					continue
				}

				matches := regexpv.HttpMappingRegExp(cText)
				if len(matches) > 0 {
					routerFuncRegister(router, v, funcDecl, prefix, matches[0][1])
				}
			}
		}
	}
}

func routerFuncRegister(router bean.IxBaseRouter, v reflect.Value, funcDecl *ast.FuncDecl, prefix string, childPath string) {
	m := v.MethodByName(funcDecl.Name.Name)
	path := sugar.JoinWithSlash(prefix, childPath)
	if httpHandle, ok := m.Interface().(func(http.ResponseWriter, *http.Request)); ok {
		log.Printf("HttpRegister: %s\n", path)
		if path == "/login" {
			router.HandleFunc(path, httpHandle)
		} else {
			router.HandleFunc(path, httpHandle)
		}
	} else if httpHandle2, ok2 := m.Interface().(func(handler *handle.FormHandler) error); ok2 {
		log.Printf("HttpRegister: %s\n", path)
		router.HandleFunc(path, middleware.HttpContextForm(httpHandle2))
	} else if httpHandle3, ok3 := m.Interface().(func(*handle.PrimaryHandler) error); ok3 {
		log.Printf("HttpRegister: %s\n", path)
		router.HandleFunc(path, middleware.HttpContextPrimary(httpHandle3))
	} else if httpHandle4, ok4 := m.Interface().(func(*handle.EntityHandler) error); ok4 {
		log.Printf("HttpRegister: %s\n", path)
		router.HandleFunc(path, middleware.HttpContextEntity(httpHandle4))
	} else if httpHandle21, ok21 := m.Interface().(func(handler *handle.FormHandler)); ok21 {
		log.Printf("HttpRegister: %s\n", path)
		router.HandleFunc(path, middleware.HttpContextFormNoError(httpHandle21))
	} else if httpHandle31, ok31 := m.Interface().(func(*handle.PrimaryHandler)); ok31 {
		log.Printf("HttpRegister: %s\n", path)
		router.HandleFunc(path, middleware.HttpContextPrimaryNoError(httpHandle31))
	} else if httpHandle41, ok41 := m.Interface().(func(*handle.EntityHandler)); ok41 {
		log.Printf("HttpRegister: %s\n", path)
		router.HandleFunc(path, middleware.HttpContextEntityNoError(httpHandle41))
	} else {
		log.Fatalf("HttpRegister：【%v】参数异常.", path)
	}
}

//endregion

//region 默认HttpHandle注册

func HttpRegister(filePath string, v reflect.Value, fs *embed.FS) {
	//typ := reflect.TypeOf(structTyp)
	//if typ.Kind() == reflect.Ptr {
	//	typ = typ.Elem() // 如果是指针类型，获取指向的元素类型
	//}
	//v := reflect.ValueOf(structTyp)

	//_, filePath, _, ok := runtime.Caller(1)
	//if !ok {
	//	log.Fatal("无法获取当前文件路径")
	//}

	//method, _ := typ.MethodByName("ActionInitialize")
	//if !method.Func.IsValid() {
	//	log.Print("方法名ActionInitialize不存在，无法获取当前文件路径")
	//	return
	//}
	//filePath, _ := runtime.FuncForPC(method.Func.Pointer()).FileLine(0)

	//log.Println("当前文件路径:", filePath)

	//跳过代码自动生成的HTTP注册
	if strings.Index(filePath, "generate") > 0 {
		return
	}

	// 读取文件内容
	src, err := os.ReadFile(filePath)
	if err != nil {
		//编译包必须使用内嵌文件读取，正常编译不会包含源码文件
		src, err = fs.ReadFile("public" + strings.Split(filePath, "public")[1])
		if err != nil {
			log.Fatalf("Failed to read file: %v", err)
		}
	}

	// 创建一个文件集
	fSet := token.NewFileSet()

	file1, err2 := parser.ParseFile(fSet, filePath, src, parser.ParseComments)
	if err2 != nil {
		log.Fatalf("Failed to read file: %v", err2)
	}

	var prefix string
	//遍历循环所有声明，包含【import、init、struct[GenDecl]、func[FuncDecl]】
	for _, decl := range file1.Decls {
		//判断GenDecl声明，针对结构体Action设定路径 ActionMapping("")
		if genDecl, ok := decl.(*ast.GenDecl); ok && genDecl.Tok == token.TYPE {
			if genDecl.Doc != nil {
				for _, comment := range genDecl.Doc.List {
					//log.Printf("Found comment: %s\n", comment.Text)
					actionMapping := regexpv.SwaggerRouterRegExp(comment.Text)
					if len(actionMapping) > 0 {
						prefix = actionMapping[0][1]
						log.Printf("ActionMapping: %s\n", actionMapping[0][1])
					}
				}
			}
		}

		//判断FuncDecl声明，对相关action方法进行注册
		if funcDecl, okFunc := decl.(*ast.FuncDecl); okFunc && funcDecl.Doc != nil {
			for _, comment := range funcDecl.Doc.List {
				//log.Printf("Found comment: %s\n", comment.Text)
				cText := comment.Text

				//根据swagger方式进行路由注册
				matches1 := regexpv.SwaggerRouterRegExp(cText)
				if len(matches1) > 0 {
					handlerFuncRegister(v, funcDecl, prefix, matches1[0][1])
					continue
				}

				matches := regexpv.HttpMappingRegExp(cText)
				if len(matches) > 0 {
					handlerFuncRegister(v, funcDecl, prefix, matches[0][1])
				}
			}
		}
	}
}

func handlerFuncRegister(v reflect.Value, funcDecl *ast.FuncDecl, prefix string, childPath string) {
	//log.Printf("Found func: %s\n", funcDecl.Name.Name)
	m := v.MethodByName(funcDecl.Name.Name)
	path := sugar.JoinWithSlash(prefix, childPath)
	if httpHandle, ok := m.Interface().(func(http.ResponseWriter, *http.Request)); ok {
		log.Printf("HttpRegister: %s\n", path)
		if path == "/login" {
			http.HandleFunc(path, httpHandle)
		} else {
			http.HandleFunc(path, middleware.MidAuth(httpHandle))
		}
	} else if httpHandle2, ok2 := m.Interface().(func(handler *handle.FormHandler) error); ok2 {
		log.Printf("HttpRegister: %s\n", path)
		http.HandleFunc(path, middleware.MidAuth(middleware.HttpContextForm(httpHandle2)))
	} else if httpHandle3, ok3 := m.Interface().(func(*handle.PrimaryHandler) error); ok3 {
		log.Printf("HttpRegister: %s\n", path)
		http.HandleFunc(path, middleware.MidAuth(middleware.HttpContextPrimary(httpHandle3)))
	} else if httpHandle4, ok4 := m.Interface().(func(*handle.EntityHandler) error); ok4 {
		log.Printf("HttpRegister: %s\n", path)
		http.HandleFunc(path, middleware.MidAuth(middleware.HttpContextEntity(httpHandle4)))
	} else if httpHandle21, ok21 := m.Interface().(func(handler *handle.FormHandler)); ok21 {
		log.Printf("HttpRegister: %s\n", path)
		http.HandleFunc(path, middleware.MidAuth(middleware.HttpContextFormNoError(httpHandle21)))
	} else if httpHandle31, ok31 := m.Interface().(func(*handle.PrimaryHandler)); ok31 {
		log.Printf("HttpRegister: %s\n", path)
		http.HandleFunc(path, middleware.MidAuth(middleware.HttpContextPrimaryNoError(httpHandle31)))
	} else if httpHandle41, ok41 := m.Interface().(func(*handle.EntityHandler)); ok41 {
		log.Printf("HttpRegister: %s\n", path)
		http.HandleFunc(path, middleware.MidAuth(middleware.HttpContextEntityNoError(httpHandle41)))
	} else {
		log.Fatalf("HttpRegister：【%v】参数异常.", path)
	}
}

//endregion
